#include "stdafx.h"
#include "Lexer.h"

NToken::NToken()
{
	m_Content = L"";
	m_Type = ttNull;
	m_Line = -1;
}

NToken::NToken(NWString Content, RegexTokenType Type, int Line)
{
	m_Content = Content;
	m_Type = Type;
	m_Line = Line;
}

NToken::~NToken()
{
}

NTokenRegex::NTokenRegex(NWString Expression,RegexTokenType Type,BOOL Exit)
{
	TheRegex = new Regex(Expression);
	this->Type = Type;
	this->Exit = Exit;
}

void NLexer::Lexer(NWString wCode)
{
	LPTSTR Content = wCode.GetBuffer();
	int nLine = 1;
	while(*Content)
	{
		BOOL bSuccessful = FALSE;
		for(int i=0;i<RegexListCount;i++)
		{
			Regex::MathResult TheMatchResult = RegexList[i]->TheRegex->Match(Content);
			if(TheMatchResult.Matched)
			{
				//wprintf(L"%sbbb\n",TheMatchResult.Result);
				//wprintf(L"%saaa\n",Content);
				NAutoPtr<NTokenRegex> TokenRegex = RegexList[i];
				if(TokenRegex->Type == ttEnter) nLine++;
				if(TokenRegex->Exit)
				{
					m_Tokens.Add(new NToken(TheMatchResult.Result,TokenRegex->Type,nLine));
				}
				bSuccessful = TRUE;
				Content += TheMatchResult.Length;
				break;
			}
		}
		if (!bSuccessful)
		{
			/*CString Temp = Content;
			Temp = Temp.Left(1);
			ErrorTokens.AddLast()->Data=new Token(Temp, regularERROR, Position);*/
			//wprintf(L"%saaa\n",Content);
			Content++;
		}
	}
	/*LPTSTR Content = wCode.GetBuffer(wCode.GetLength());
	wCode.ReleaseBuffer();
	NAutoPtr<NToken> Token;
	while((Token = GetToken(Content))->m_Type != ttNull) m_Tokens.AddLast()->Data = Token;*/
}

void NLexer::Print()
{
	int iPos = 0;
	while(iPos < m_Tokens.Size())
	{
		wprintf(L"Line:%d Content:%s Type:%d",m_Tokens[iPos]->m_Line,m_Tokens[iPos]->m_Content,m_Tokens[iPos]->m_Type);
		switch(m_Tokens[iPos]->m_Type)
		{
		case ttString:
			wprintf(L"(String)");
			break;
		case ttOperator:
			wprintf(L"(Operator)");
			break;
		case ttSymbol:
			wprintf(L"(Symbol)");
			break;
		case ttSpace:
			wprintf(L"(Space)");
			break;
		case ttEnter:
			wprintf(L"(Enter)");
			break;
		case ttNull:
			wprintf(L"(Null)");
			break;
		}
		wprintf(L"\n");
		iPos++;
	}
}

NLexer::NLexer()
{
	RegexList.Add(new NTokenRegex(L":", ttOperator ,TRUE));
	RegexList.Add(new NTokenRegex(L";", ttOperator ,TRUE));
	RegexList.Add(new NTokenRegex(L"\\(",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L")",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"{",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"}",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"\\[",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"]",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L",",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L">=",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"<=",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"==",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L">",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"<",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"=",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"\\+",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"-",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"\\*",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"/",ttOperator,TRUE));
	RegexList.Add(new NTokenRegex(L"(	)+",ttSpace,FALSE));
	RegexList.Add(new NTokenRegex(L"( )+", ttSpace ,FALSE));
	RegexList.Add(new NTokenRegex(L"\n", ttEnter ,FALSE));
	RegexList.Add(new NTokenRegex(L"\"([^\"]|[\\\\]\")*\"", ttString,TRUE));
	RegexList.Add(new NTokenRegex(L"[_a-zA-Z]+([_0-9a-zA-Z])*", ttSymbol, TRUE));
	RegexList.Add(new NTokenRegex(L"[0-9]*.[0-9]+",ttNumber,TRUE));
	RegexList.Add(new NTokenRegex(L"[0-9]+",ttNumber,TRUE));
	RegexListCount = RegexList.Size();
}